#include "statisticspage.h"
#include "ui_statisticspage.h"
#include <QJsonArray>
#include <QLayoutItem>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QValueAxis>
#include <QToolTip>
#include <QMessageBox>
#include <cmath>
#include <QList>
#include <QTimer>
#include <QFileDialog>
#include <QPdfWriter>
#include <QAxObject>
#include "protocol.h"
QT_CHARTS_USE_NAMESPACE

StatisticsPage::StatisticsPage(QWidget *parent,QTcpSocket* externalSocket) :
    QWidget(parent),
    ui(new Ui::StatisticsPage),
    socket(externalSocket)
{
    ui->setupUi(this);

    QVBoxLayout* mainLayout = new QVBoxLayout(this);// 主布局
    this->setLayout(mainLayout);

    // 图表容器
    chartContainer = new QWidget(this);
    chartLayout = new QVBoxLayout(chartContainer);
    chartContainer->setLayout(chartLayout);
    mainLayout->addWidget(chartContainer);

    QHBoxLayout* topLayout = new QHBoxLayout();
    refreshButton = new QPushButton("刷新今天数据");
    queryButton = new QPushButton("查询指定日期数据");
    dateEdit = new QDateEdit(QDate::currentDate());
    dateEdit->setCalendarPopup(true); // 弹出日历选择
    exportButton = new QPushButton("导出当前图表");

    topLayout->addWidget(exportButton);
    topLayout->addWidget(refreshButton);
    topLayout->addWidget(dateEdit);
    topLayout->addWidget(queryButton);
    mainLayout->addLayout(topLayout);
    connect(refreshButton, &QPushButton::clicked, this, &StatisticsPage::onRefreshClicked);
    connect(queryButton, &QPushButton::clicked, this, &StatisticsPage::onQueryButtonClicked);
    connect(exportButton, &QPushButton::clicked, this, &StatisticsPage::onExportClicked);
}

StatisticsPage::~StatisticsPage()
{
    delete ui;
}

void StatisticsPage::handleServerMessage(const QJsonObject &json)
{
    int func = json["func2"].toInt();
    const QJsonObject message = json["message2"].toObject();
    if(func==1)
    {
        handleCurrentStatistic(message);
    }
    else
    {
        handlePreviousStatistic(message);
    }
}
/*
void StatisticsPage::handleCurrentStatistic(const QJsonObject &json)
{
    QString stat_date = json["stat_date"].toString();
    QString entry_count = json["entry_count"].toString();
    QString exit_count = json["exit_count"].toString();
    QString total_income = json["total_income"].toString();
    QString usage_rate = json["usage_rate"].toString();
    QString reservation_cnt = json["reservation_cnt"].toString();
    QString reservation_rt = json["reservation_rt"].toString();

    qDebug() << "stat_date" << stat_date;
    qDebug() << "entry_count" << entry_count;
    qDebug() << "exit_count" << exit_count;
    qDebug() << "total_income" << total_income;
    qDebug() << "usage_rate" << usage_rate;
    qDebug() << "reservation_cnt" << reservation_cnt;
    qDebug() << "reservation_rt" << reservation_rt;

    QStringList categories = {"入场数", "出场数", "收入", "使用率(%)", "预约数", "预约率(%)"};
    QList<QString> strValues = {entry_count, exit_count, total_income, usage_rate, reservation_cnt, reservation_rt};

    // 清除旧图表
    QLayoutItem* item;
    while ((item = chartLayout->takeAt(0)) != nullptr) {
        if (item->widget()) delete item->widget();
        delete item;
    }

    QBarSet* set = new QBarSet(stat_date);
    QList<double> numericValues;
    const double offset = 1.0; // 避免 log(0)
    for (const QString& s : strValues) {
        double val = s.toDouble();
        //numericValues.append(log10(val + offset));
        numericValues.append(val);
        *set << val;
    }

    QBarSeries* series = new QBarSeries();
    series->append(set);

    QChart* chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("停车场统计数据柱状图(当前) - " + stat_date);
    chart->setAnimationOptions(QChart::SeriesAnimations);

    QBarCategoryAxis* axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    QValueAxis* axisY = new QValueAxis();
    axisY->setRange(0, *std::max_element(numericValues.begin(), numericValues.end()) * 1.2);
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);

    QChartView* chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    chartLayout->addWidget(chartView);


    connect(set, &QBarSet::hovered, this, [=](bool status, int index) {
        if (status) {
            QString tip = categories[index] + ": " + strValues[index];
            QToolTip::showText(QCursor::pos(), tip);
        } else {
            QToolTip::hideText();
        }
    });
}*/


void StatisticsPage::handleCurrentStatistic(const QJsonObject &json)
{
    stat_date = json["stat_date"].toString();
    entry_count = json["entry_count"].toString();
    exit_count = json["exit_count"].toString();
    total_income = json["total_income"].toString();
    usage_rate = json["usage_rate"].toString();
    reservation_cnt = json["reservation_cnt"].toString();
    reservation_rt = json["reservation_rt"].toString();

    QStringList categories = {"入场数", "出场数", "收入", "使用率(%)", "预约数", "预约率(%)"};
    QList<QString> strValues = {entry_count, exit_count, total_income, usage_rate, reservation_cnt, reservation_rt};

    // 清除旧图表
    QLayoutItem* item;
    while ((item = chartLayout->takeAt(0)) != nullptr) {
        if (item->widget()) delete item->widget();
        delete item;
    }

    QBarSet* set = new QBarSet(stat_date);
    QList<double> numericValues;
    for (const QString& s : strValues) {
        double val = s.toDouble();
        numericValues.append(val);
        *set << val;
    }

    QBarSeries* series = new QBarSeries();
    series->append(set);


    //显示柱子上的数值标签（自适应缩放）
    series->setLabelsVisible(true);
    series->setLabelsFormat("@value");
    series->setLabelsPosition(QAbstractBarSeries::LabelsOutsideEnd);
    set->setLabelColor(Qt::black);


    QChart* chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("停车场统计数据柱状图(当前) - " + stat_date);
    chart->setAnimationOptions(QChart::SeriesAnimations);

    QBarCategoryAxis* axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    QValueAxis* axisY = new QValueAxis();
    axisY->setRange(0, *std::max_element(numericValues.begin(), numericValues.end()) * 1.2);
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);

    // 创建图表视图
    QChartView* chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    chartLayout->addWidget(chartView);



    // 鼠标悬停提示
    connect(set, &QBarSet::hovered, this, [=](bool status, int index) {
        if (status) {
            QString tip = categories[index] + ": " + strValues[index];
            QToolTip::showText(QCursor::pos(), tip);
        } else {
            QToolTip::hideText();
        }
    });
}


void StatisticsPage::handlePreviousStatistic(const QJsonObject &json)
{
    stat_date = json["stat_date"].toString();
    entry_count = json["entry_count"].toString();
    exit_count = json["exit_count"].toString();
    total_income = json["total_income"].toString();
    usage_rate = json["usage_rate"].toString();
    reservation_cnt = json["reservation_cnt"].toString();
    reservation_rt = json["reservation_rt"].toString();
    int isValidDate = json["bool"].toInt();
    if(!isValidDate)
    {
        QMessageBox *msg = new  QMessageBox(this);
        msg->setWindowTitle("警告");
        msg->setText("无当前日期的数据");
        msg->setIcon(QMessageBox::Critical);
        msg->show();
        return;
    }

    qDebug() << "stat_date" << stat_date;
    qDebug() << "entry_count" << entry_count;
    qDebug() << "exit_count" << exit_count;
    qDebug() << "total_income" << total_income;
    qDebug() << "usage_rate" << usage_rate;
    qDebug() << "reservation_cnt" << reservation_cnt;
    qDebug() << "reservation_rt" << reservation_rt;

    QStringList categories = {"入场数", "出场数", "收入", "使用率(%)", "预约数", "预约率(%)"};
    QList<QString> strValues = {entry_count, exit_count, total_income, usage_rate, reservation_cnt, reservation_rt};

    // 清除旧图表
    QLayoutItem* item;
    while ((item = chartLayout->takeAt(0)) != nullptr) {
        if (item->widget()) delete item->widget();
        delete item;
    }


    QBarSet* set = new QBarSet(stat_date);
    QList<double> numericValues;
    const double offset = 1.0; // 避免 log(0)
    for (const QString& s : strValues) {
        double val = s.toDouble();
        //numericValues.append(log10(val + offset));  //这里为了图标更美观，使用了对数缩放
        numericValues.append(val);
        *set << val;
    }

    QBarSeries* series = new QBarSeries();
    series->append(set);


    //显示柱子上的数值标签（自适应缩放）
    series->setLabelsVisible(true);
    series->setLabelsFormat("@value");
    series->setLabelsPosition(QAbstractBarSeries::LabelsOutsideEnd);
    set->setLabelColor(Qt::black);


    QChart* chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("停车场统计数据柱状图 - " + stat_date);
    chart->setAnimationOptions(QChart::SeriesAnimations);

    QBarCategoryAxis* axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    QValueAxis* axisY = new QValueAxis();
    axisY->setRange(0, *std::max_element(numericValues.begin(), numericValues.end()) * 1.2);
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);

    QChartView* chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    chartLayout->addWidget(chartView);

    connect(set, &QBarSet::hovered, this, [=](bool status, int index) {
        if (status) {
            QString tip = categories[index] + ": " + strValues[index];
            QToolTip::showText(QCursor::pos(), tip);
        } else {
            QToolTip::hideText();
        }
    });
}


void StatisticsPage::onRefreshClicked()
{
    QJsonObject root;
    QJsonObject message;
    root["func"] = 11;
    root["message"] = message;
    QByteArray dataToSend = Encode(root);
    socket->write(dataToSend);
}

void StatisticsPage::onQueryButtonClicked()
{
    QDate date = dateEdit->date();
    QDate currentDate = QDate::currentDate();
    //qDebug()<<date;
    QString dateStr = date.toString("yyyy-MM-dd");
    //qDebug()<<dateStr;
    if(date>currentDate)
    {
        QMessageBox *msg = new  QMessageBox(this);
        msg->setWindowTitle("警告");
        msg->setText("请勿查看未来日期的数据");
        msg->setIcon(QMessageBox::Critical);
        msg->show();
        return;
    }
    if(date==currentDate)
    {
        onRefreshClicked();
        return;
    }

    QJsonObject root;
    QJsonObject message;
    root["func"] = 12;
    message["date"] = dateStr;
    root["message"] = message;
    QByteArray dataToSend = Encode(root);
    socket->write(dataToSend);
}


void StatisticsPage::onExportClicked()
{
    if (chartLayout->count() == 0) return;

    QChartView* chartView = qobject_cast<QChartView*>(chartLayout->itemAt(0)->widget());
    if (!chartView) return;

    QMessageBox msgBox(this);
    msgBox.setWindowTitle("选择导出类型");
    msgBox.setText("请选择导出文件的类型：");
    QPushButton* imageBtn = msgBox.addButton("图片", QMessageBox::AcceptRole);
    QPushButton* pdfBtn = msgBox.addButton("PDF", QMessageBox::AcceptRole);
    QPushButton* excelBtn = msgBox.addButton("Excel表格", QMessageBox::AcceptRole);
    msgBox.addButton("取消", QMessageBox::RejectRole);
    msgBox.exec();
    if (msgBox.clickedButton() == imageBtn)
    {
        QString defaultName = "停车场统计数据柱状图 - "+stat_date;
        QString fileName = QFileDialog::getSaveFileName(this, "保存图表为图片", defaultName, "PNG 图片 (*.png);;JPG 图片 (*.jpg)");
        if (fileName.isEmpty()) return;

        QPixmap pixmap(chartView->size());
        QPainter painter(&pixmap);
        chartView->render(&painter);
        painter.end();
        pixmap.save(fileName);
    }
    else if (msgBox.clickedButton() == pdfBtn)
    {
        QString defaultName = "停车场统计数据柱状图 - "+stat_date;
        QString fileName = QFileDialog::getSaveFileName(this, "保存为 PDF",defaultName, "PDF 文件 (*.pdf)");

        if (fileName.isEmpty()) return;

        QPdfWriter writer(fileName);
        writer.setPageSize(QPageSize(chartView->size()));
        QPainter painter(&writer);
        chartView->render(&painter);
        painter.end();
    }
    else if (msgBox.clickedButton() == excelBtn)
    {
        exportToExcel();
    }
    else
    {
        qDebug()<<"取消";
    }
}



void StatisticsPage::exportToExcel()
{
    QString filePath = QFileDialog::getSaveFileName(this, "导出为 Excel",
                       "停车场统计数据-" + stat_date + ".xlsx", "Excel 文件 (*.xlsx)");
    if (filePath.isEmpty()) return;

    QAxObject *excel = new QAxObject("Excel.Application", this);
    excel->setProperty("Visible", false); // 不显示 Excel 界面

    QAxObject *workbooks = excel->querySubObject("Workbooks");
    workbooks->dynamicCall("Add");
    QAxObject *workbook = excel->querySubObject("ActiveWorkbook");
    QAxObject *sheet = workbook->querySubObject("Worksheets(int)", 1);

    // 写入表头
    sheet->querySubObject("Cells(int,int)", 1, 1)->setProperty("Value", "日期");
    sheet->querySubObject("Cells(int,int)", 1, 2)->setProperty("Value", "入场数");
    sheet->querySubObject("Cells(int,int)", 1, 3)->setProperty("Value", "出场数");
    sheet->querySubObject("Cells(int,int)", 1, 4)->setProperty("Value", "收入");
    sheet->querySubObject("Cells(int,int)", 1, 5)->setProperty("Value", "使用率(%)");
    sheet->querySubObject("Cells(int,int)", 1, 6)->setProperty("Value", "预约数");
    sheet->querySubObject("Cells(int,int)", 1, 7)->setProperty("Value", "预约率(%)");

    // 写入数据
    sheet->querySubObject("Cells(int,int)", 2, 1)->setProperty("Value", stat_date);
    sheet->querySubObject("Cells(int,int)", 2, 2)->setProperty("Value", entry_count);
    sheet->querySubObject("Cells(int,int)", 2, 3)->setProperty("Value", exit_count);
    sheet->querySubObject("Cells(int,int)", 2, 4)->setProperty("Value", total_income);
    sheet->querySubObject("Cells(int,int)", 2, 5)->setProperty("Value", usage_rate);
    sheet->querySubObject("Cells(int,int)", 2, 6)->setProperty("Value", reservation_cnt);
    sheet->querySubObject("Cells(int,int)", 2, 7)->setProperty("Value", reservation_rt);

    // 保存文件
    workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(filePath));
    workbook->dynamicCall("Close()");
    excel->dynamicCall("Quit()");

    delete excel;
    //QMessageBox::information(this, "导出成功", "数据已成功导出为 Excel 文件！");
}




